package com.ai.utils;

//import java.security.Key;
//import java.security.NoSuchAlgorithmException;
//import java.security.SecureRandom;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;

//import sun.misc.BASE64Decoder;
//import sun.misc.BASE64Encoder;

/**
*
* 使用DES加密,可对byte[],String类型进行加密
*/

public class DesEncrypt {

	private static final Logger log = LoggerFactory.getLogger(DesEncrypt.class);

	static final char[] hexChars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
		'A', 'B', 'C', 'D', 'E', 'F' };

	static final byte[] desKeyData =
	{(byte)0xF4, (byte)0x88, (byte)0xFD, (byte)0x58,
	 (byte)0x4E, (byte)0x49, (byte)0xDB, (byte)0xCD,
	 (byte)0x20, (byte)0xB4, (byte)0x9D, (byte)0xE4,
	 (byte)0x91, (byte)0x07, (byte)0x36, (byte)0x6B,
	 (byte)0x33, (byte)0x6C, (byte)0x38, (byte)0x0D,
	 (byte)0x45, (byte)0x1D, (byte)0x0F, (byte)0x7C,
	};

	/**
	 * 加密函数
	 * @param strPass
	 * @return
	 */
	public static String encryptTriDes(String strPass)
	{
		/*
	{'\0xF4','\0x88','\0xFD','\0x58','\0x4E','\0x49','\0xDB','\0xCD'},
	{'\0x20','\0xB4','\0x9D','\0xE4','\0x91','\0x07','\0x36','\0x6B'},
	{'\0x33','\0x6C','\0x38','\0x0D','\0x45','\0x1D','\0x0F','\0x7C'},
		 */
		try
		{
			byte[] pass = strPass.getBytes("UTF-8");
			int tail = pass.length % 8;
			int block = pass.length / 8 + 1;
			byte fill = (byte) (8 - tail);
			byte[] fillPass = new byte[block*8];
			System.arraycopy(pass, 0, fillPass, 0, pass.length);
			for (int i=0;i<8-tail;i++)
				fillPass[pass.length+i] = fill;
//			System.out.println(toHexString(fillPass));

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			DESedeKeySpec desKeySpec = new DESedeKeySpec(desKeyData);
			SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
			Cipher cipher = Cipher.getInstance("DESede");
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);

			byte[] result = new byte[block*8];
			for (int i=0; i<block; i++)
			{
				byte[] tmp = cipher.doFinal(fillPass, i*8, 8);
				System.arraycopy(tmp, 0, result, i*8, 8);
			}
			String strResult = toHexString(result);
			return strResult;
		}catch (Exception e)
		{
			e.printStackTrace(System.err);
			return null;
		}
	}

	/**
	 * 解密函数
	 * @param strPass
	 * @return
	 */
	public  static String TriDesDecrypt(String strPass)
	{
		try
		{
			byte[] pass = toByteArray(strPass);
			int block = pass.length / 8;

			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
			DESedeKeySpec desKeySpec = new DESedeKeySpec(desKeyData);
			SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
			Cipher cipher = Cipher.getInstance("DESede");
			cipher.init(Cipher.DECRYPT_MODE, secretKey);

			byte[] result = new byte[block*8];
			for (int i=0; i<block; i++)
			{
				byte[] tmp = cipher.doFinal(pass, i*8, pass.length-i*8);
				System.arraycopy(tmp, 0, result, i*8, tmp.length);
			}
			int realLen = result.length;
			for (int i=0; i<result.length; i++)
			{
				if (result[i]==0)
				{
					realLen = i;
					break;
				}
			}
			String strResult = new String(result,0,realLen,"UTF-8");
			return strResult;
		}catch (Exception e)
		{
			e.printStackTrace(System.err);
			return null;
		}
	}


    /*
	 * Converts a byte to hex digit and writes to the supplied buffer
	 */
	private  static  void byte2hex(byte b, StringBuffer buf)
	{
		int high = ((b & 0xf0) >> 4);
		int low = (b & 0x0f);
		buf.append(hexChars[high]);
		buf.append(hexChars[low]);
	}

	/*
	 * Converts a byte array to hex string
	 */
	private  static String toHexString(byte[] block)
	{
		int len = block.length;
		StringBuffer buf = new StringBuffer(len*2);
		for (int i = 0; i < len; i++)
		{
			byte2hex(block[i], buf);
		}
		return buf.toString();
	}

	private  static  byte[] toByteArray(String hexStr)
	{
		int len = hexStr.length()/2;
		byte[] arr = new byte[len];
		for (int i=0; i<len; i++)
		{
			arr[i] = (byte) Integer.parseInt(hexStr.substring(i*2, i*2+2),16);
		}
		return arr;
	}

	/**
	 * 加密数据
	 * @param str
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encrypt(String str, String key)
			throws Exception {

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		cipher.init(Cipher.ENCRYPT_MODE, secretKey);
		byte[] byteMi = cipher.doFinal(str.getBytes("utf-8"));
		return byteMi;

	}

	/**
	 * 解密数据
	 * @param bytes
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decrypt(byte[] bytes, String key)
			throws Exception {

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		DESKeySpec desKeySpec = new DESKeySpec(key.getBytes());
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		cipher.init(Cipher.DECRYPT_MODE, secretKey);
		byte[] byteMi = cipher.doFinal(bytes);
		return new String(byteMi);

	}

	/**
	 * 数据解密
	 * @param str
	 * @param key
	 * @return
	 */
	public static String decryptpar(String str, String key) {
		try {
			return decrypt(com.ai.utils.Base64Util.decode(str), key);
		} catch (Exception e) {
			log.error("数据DES解密异常:{}" + e.getMessage(), e);
		}
		return null;
	}


	public static void main(String[] args){


		String pwd ="Cqeip@369";
		String desPwd ="2B23BFC6D73B6AC4F108C7D06C3DCCE0";

		DesEncrypt encrypt = new DesEncrypt();

		String jiapwd =encrypt.encryptTriDes(pwd);

		String jiePwd = encrypt.TriDesDecrypt(desPwd);
		System.out.println(jiapwd);
		System.out.println(jiePwd);
	}

}



